#include "ui_part2dwidget.h"
#include "ui_manager.h"
#include "camera/abstract_camera.h"
#include "math/plane.h"
#include "part2d/part2d.h"
#include "num/rand.h"


#include "audio/audio.h"

#include "util/timer.h"		    // Needs to come in early
#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros
#include "util/log.h"		    // logging

#include "script/scripthelper.h"
#include "script/write_lua.h"


#ifdef _ENABLE_LUABIND
#include <luabind/luabind.hpp>
#endif // _ENABLE_LUABIND


using namespace ui;
using namespace script;


UIPart2DWidget::UIPart2DWidget(UIWidget* pParent,const std::string& Name) :
	UIWidget(pParent, Name),
	m_pPartSys(NULL),
	m_Paused(false),
	m_PostRender(false)
{
	m_Type = WT_PART2DWIDGET;
}

UIPart2DWidget::~UIPart2DWidget()
{
	UTIL_SAFE_DELETE(m_pPartSys);
}

bool		UIPart2DWidget::Create(const std::string& Name, const math::Vec2& Pos, const math::Vec2& Size)
{

	UIWidget::Create(Name, Pos, Size);
	// create progress stuff

	return true;
}

bool		UIPart2DWidget::Load(LuaPlus::LuaObject& _LObj)
{
	UIWidget::Load(_LObj);	// get all the common stuff loaded
	std::string PartSys		= ScriptHelper::GetTableString(_LObj, "Partsys", "");
	m_PostRender			= ScriptHelper::GetTableBool(_LObj, "ForceOnTop", false);
	SetPartFile(PartSys);
	return true;
}
bool		UIPart2DWidget::ExportSpecificsToFile(script::WriteLua*	pWL)
{
	if (m_pPartSys)
	{
		pWL->WritePair("Partsys", m_pPartSys->GetFile());
		pWL->WritePair("ForceOnTop", (m_PostRender) ? 1 : 0);
	}
	return true;
}

bool		UIPart2DWidget::Tick(float dt)
{
	UIWidget::Tick(dt);	// tick children, etc
	if (m_pPartSys && !m_Paused )
	{
		m_pPartSys->SetPos(GetPosition());
		num::RAND32& Rnd = num::RAND32::Instance();
		for (int i=0; i<m_pPartSys->GroupC(); i++)
		{
			if (m_pPartSys->GetGroup(i)->ShouldCreateParticle(dt))
			{
				do 
				{
					m_pPartSys->GetGroup(i)->TriggerParticle(Rnd.RandVec2(GetPosition(), GetPosition()+GetSize()));
				} while (m_pPartSys->GetGroup(i)->ShouldCreateParticle(0));
			}
		}
	}
	m_pPartSys->Tick(dt);
	return true;
}

void		UIPart2DWidget::ClearParticles()
{
	if (m_pPartSys)
	{
		for (int i=0; i<m_pPartSys->GroupC(); i++)
		{
			m_pPartSys->GetGroup(i)->ClearParticles();
		}
	}
}


void		UIPart2DWidget::SavePartFile(const std::string& File)
{
	if (m_pPartSys)
	{
		m_pPartSys->Save(File);
	}
}

void		UIPart2DWidget::SetPartFile(const std::string& File)
{
	if (m_pPartSys && m_pPartSys->GetFile() == File) 
	{
		_LOG(MSG_WARNING, "Trying to re-set the file. Reset instead?");
		return;
	}
	UTIL_SAFE_DELETE(m_pPartSys);
	if (File.empty()) return;	// empty file
	m_pPartSys = new part2d::Part2D();
	m_pPartSys->Load(File);
}


void UIPart2DWidget::PostRender()
{
	if (!m_PostRender) return;
	if (!m_IsVisible  || !m_IsActive) return;
	if (m_pPartSys)
	{
		if (m_pManager->GetCamera())
		{
			m_pPartSys->Render(math::Vec2(0,0), 1);
		}
	}
	UIWidget::PostRender();
}

bool	UIPart2DWidget::Render(bool Force )
{
	if (!m_IsVisible  || !m_IsActive) return false;
	if (!m_PostRender)
	{
		if (m_pPartSys)
		{
			if (m_pManager->GetCamera())
			{
				m_pPartSys->Render(math::Vec2(0,0), 1);
			}
		}
	}
	if (m_pManager) m_pManager->WidgetRendered();
	for (ElementList::iterator It = m_Set.begin(); It != m_Set.end(); It++)
	{
			It->second->Render();
	}
	return true;
}

UIWidget*	UIPart2DWidget::GetClone()
{
	UIPart2DWidget*	pNew = new UIPart2DWidget(m_pParent, GetCloneName(m_Name));
	FillCloneInfo((UIWidget*)pNew);
	return pNew;
}


void	UIPart2DWidget::TriggerParticles(int Count)
{
	if (m_pPartSys)
	{
		for (int i=0; i<Count; i++)
		{
			math::Vec2	Pos = num::RAND32::Instance().RandVec2(m_Pos, m_Pos+m_Size);
			m_pPartSys->TriggerParticle(Pos);
		}
	}
}


/// register with LUA Bind
void	UIPart2DWidget::Register(LuaPlus::LuaState* _pScript)
{
#ifdef _ENABLE_LUABIND
    lua_State * L = _pScript->GetCState ( );

	luabind::module(L)
    [

		luabind::class_<UIPart2DWidget, UIWidget >( "Part2DWidget" )
		.def( "SetPartFile",		&UIPart2DWidget::SetPartFile)
		.def( "SavePartFile",		&UIPart2DWidget::SavePartFile)
		.def( "IsPaused",			&UIPart2DWidget::IsPaused)
		.def( "SetPaused",			&UIPart2DWidget::SetPaused)
		.def( "GetPartsys",			&UIPart2DWidget::GetPartsys)
		.def( "TriggerParticles",   &UIPart2DWidget::TriggerParticles)
		.def( "ClearParticles",		&UIPart2DWidget::ClearParticles)
		
	];

	// register the partsys here?
	part2d::Part2D::Register(_pScript);
	#endif // _ENABLE_LUABIND    

}
